/*****************************
 *@file: BaseBulletComp
 *@author: 陈吕唐
 *@desc: 基础子弹组件
 *@date: 2024-03-08	11:35
 *****************************/
import { _decorator, Collider2D, Component, Contact2DType, IPhysics2DContact, math, NodePool, RigidBody2D, v2, warn } from 'cc';
import { HurtTypeEnum } from '../core/enum/HurtTypeEnum';
import IBaseBullet from '../core/fight/IBaseBullet';
import IBaseFight from '../core/fight/IBaseFight';
import { MBoxGroup } from '../MBoxGroup';
const { ccclass, property } = _decorator;

@ccclass('BaseBulletComp')
export class BaseBulletComp extends Component implements IBaseBullet {

    /****************************************************************************************************************
     *Readonly 常量
     ****************************************************************************************************************/
    /****************************************************************************************************************
     *Property 定义变量
     ****************************************************************************************************************/
    /**
     * 伤害类型
     */
    public type: HurtTypeEnum = HurtTypeEnum.NORMAL;

    /**
     * 发射者
     */
    public source: IBaseFight;


    /**
     * 子弹伤害/治疗值
     */
    public value: number;
    /***************************************************************
    *PropertyUI 引用的控件
    ***************************************************************/
    @property({ group: { name: 'BULLET', id: '1' }, type: RigidBody2D, tooltip: `子弹刚体` })
    protected body: RigidBody2D = undefined!;

    @property({ group: { name: 'BULLET', id: '1' }, type: Collider2D, tooltip: `当前碰撞实体形状(默认从当前节点查找)` })
    protected bodyCollider: Collider2D = null;
    /**
     * 对象池
     */
    protected pool: NodePool = undefined!;
    /****************************************************************************************************************
     * Lifecycle 生命周期相关方法
     ****************************************************************************************************************/
    protected onEnable(): void {
        if (!this.body) {
            this.body = this.getComponent(RigidBody2D);
        }

        let colliders = this.node.getComponents(Collider2D);
        if (!this.bodyCollider) {
            this.bodyCollider = colliders.find((c) => c.tag === MBoxGroup.ColliderTag.BODY);
        }

        this.addBodyListener(this.bodyCollider);
    }

    protected onDisable(): void {
        if (this.bodyCollider) {
            this.bodyCollider.targetOff(this);
        }
    }

    /**
     * 对象池使用时候使用
     */
    public reuse(args: any[]) {
        let bullet: IBaseBullet = args[0];
        this.source = bullet.source;
        this.value = bullet.value;
        this.pool = args[1];
        console.log(`当前子弹数据`)
        console.log(bullet);
    }

    /**
     * 对象池回收时候使用
     */
    public unuse() {
        this.node.setPosition(0, 0, 0);
        this.node.eulerAngles = math.Vec3.ZERO;
        this.node.setRotationFromEuler(0, 0, 0);
        this.body.linearVelocity = math.Vec2.ZERO;
        this.body.angularVelocity = 0;
        this.unscheduleAllCallbacks();
    }
    /****************************************************************************************************************
     * Public 公有方法
     ****************************************************************************************************************/
    /**
     * 碰撞到实体时候调用
     * @param selfCollider 
     * @param otherCollider 
     * @param contact 
     */
    protected onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {

    }
    /**
     * 碰撞到实体分开时候调用
     * @param selfCollider 
     * @param otherCollider 
     * @param contact 
     */
    protected onEndContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) {

    }
    /**
     * 设置子弹的速度
     * @param v 
     */
    public setLinearVelocity(v: math.Vec2): void {
        /**
         * 设置向量长度,即速度大小
         */
        let length: number = 10;
        /**
         * 设置子弹方向
         */
        v.normalize();
        v.multiplyScalar(length);
        this.body.linearVelocity = v;

        /**
         * 设置子弹旋转
         */
        let angle = -v.signAngle(v2(1, 0)) / Math.PI * 180;
        this.node.setRotationFromEuler(0, 0, angle);

        this.scheduleOnce(() => {
            this.recycleBullet();
        }, 10);

    }
    /****************************************************************************************************************
     * private 私有方法
     ****************************************************************************************************************/
    /**
     * 添加碰撞实体监听
     * @param collider 
     * @returns 
     */
    protected addBodyListener(collider: Collider2D = this.bodyCollider) {
        if (!collider) {
            warn('collider is null');
            return;
        }


        if (!collider.hasEventListener(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this)) {
            collider.on(Contact2DType.BEGIN_CONTACT, this.onBeginContact, this);
        }
        if (!collider.hasEventListener(Contact2DType.END_CONTACT, this.onEndContact, this)) {
            collider.on(Contact2DType.END_CONTACT, this.onEndContact, this);
        }
    }
    protected recycleBullet(): void {
        this.scheduleOnce(() => {
            this.unscheduleAllCallbacks()
            if (this.pool) {
                this.pool.put(this.node);
            } else {
                this.node.removeFromParent();
            }

        }, 0);
    }
    /****************************************************************************************************************
     * Property Get && Set 属性的 get && set 函数
     ****************************************************************************************************************/

}


